<template>
  <div>
    <el-row>
      <h4><b>审批人设置</b></h4>
      <el-radio-group v-model="dataType" @change="changeDataType">
        <el-radio label="USERS">指定用户</el-radio>
        <el-radio label="ROLES">角色</el-radio>
        <el-radio label="DEPTS">部门</el-radio>
        <el-radio label="INITIATOR">发起人</el-radio>
      </el-radio-group>
    </el-row>
    <el-row>
      <div v-if="dataType === 'USERS'">
        <el-tag v-for="userText in selectedUser.text" :key="userText" effect="plain">
          {{userText}}
        </el-tag>
        <div class="element-drawer__button">
          <el-button size="small" type="primary" icon="Plus" @click="onSelectUsers()">添加用户</el-button>
        </div>
      </div>
      <div v-if="dataType === 'ROLES'" style="width: 100%;">
        <el-select v-model="roleIds" multiple size="small" placeholder="请选择 角色" @change="changeSelectRoles">
          <el-option
            v-for="item in roleOptions"
            :key="item.roleId"
            :label="item.roleName"
            :value="`ROLE${item.roleId}`"
            :disabled="item.status === 1">
          </el-option>
        </el-select>
      </div>
      <div v-if="dataType === 'DEPTS'" style="width: 100%;">
        <el-tree-select
          size="small"
          :data="deptTreeData"
          :props="deptProps"
          multiple
          clearable
          checkStrictly
          show-checkbox
          default-expand-all
          value-key="id"
          v-model="selectDeptIds"
          placeholder="请选择 部门"
          @change="checkedDeptChange">
        </el-tree-select>
      </div>
    </el-row>
    <el-row>
      <div v-show="showMultiFlog">
        <el-divider />
        <h4><b>多实例审批方式</b></h4>
        <el-row>
          <el-radio-group v-model="multiLoopType" @change="changeMultiLoopType()">
            <el-row><el-radio label="Null">无</el-radio></el-row>
            <el-row class="ml10"><el-radio label="SequentialMultiInstance">会签（需所有审批人同意）</el-radio></el-row>
            <el-row><el-radio label="ParallelMultiInstance">或签（一名审批人同意即可）</el-radio></el-row>
          </el-radio-group>
        </el-row>
        <el-row v-if="multiLoopType !== 'Null'">
          <el-tooltip content="开启后，实例需按顺序轮流审批" placement="top-start" @click.stop.prevent>
            <i class="header-icon el-icon-info"></i>
          </el-tooltip>
          <span class="custom-label">顺序审批：</span>
          <el-switch v-model="isSequential" @change="changeMultiLoopType()" />
        </el-row>
      </div>
    </el-row>

    <!-- 候选用户弹窗 -->
    <el-dialog title="候选用户" v-model="userOpen" width="60%" append-to-body>
      <el-row type="flex" :gutter="20">
        <!--部门数据-->
        <el-col :span="7">
          <el-card shadow="never" style="height: 100%">
            <template #header>
              <span>部门列表</span>
            </template>
            <div class="head-container">
              <el-input
                v-model="deptName"
                placeholder="请输入部门名称"
                clearable
                size="small"
                prefix-icon="Search"
                style="margin-bottom: 20px"
              />
              <el-tree
                :data="deptOptions"
                :props="deptProps"
                :expand-on-click-node="false"
                :filter-node-method="filterNode"
                ref="tree"
                default-expand-all
                @node-click="handleNodeClick"
              />
            </div>
          </el-card>
        </el-col>
        <el-col :span="17">
          <el-table ref="multipleTable" height="600" :data="userTableList" border @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="50" align="center" />
            <el-table-column label="用户名" align="center" prop="nickName" />
            <el-table-column label="部门" align="center" prop="dept.deptName" />
          </el-table>
          <pagination
            :total="userTotal"
            v-model:page="queryParams.pageNum"
            v-model:limit="queryParams.pageSize"
            @pagination="getUserList"
          />
        </el-col>
      </el-row>
      <template #footer class="dialog-footer">
        <el-button type="primary" @click="handleTaskUserComplete">确 定</el-button>
        <el-button @click="userOpen = false">取 消</el-button>
      </template>
    </el-dialog>
  </div>

</template>

<script setup name="UserTask">
import { listUser, deptTreeSelect } from "@/api/system/user";
import { listRole } from "@/api/system/role";
// import TreeSelect from "@/components/TreeSelect";

const {proxy} = getCurrentInstance()

const userTaskForm = {
  dataType: '',
  assignee: '',
  candidateUsers: '',
  candidateGroups: '',
  text: '',
  // dueDate: '',
  // followUpDate: '',
  // priority: ''
}
const props = defineProps({
  id: String,
  type: String
})
const {id,type} = toRefs(props)

const state = reactive({
  loading: false,
  dataType: 'USERS',
  selectedUser: {
    ids: [],
    text: []
  },
  userOpen: false,
  deptName: undefined,
  deptOptions: [],
  deptProps: {
    value: 'id',
    children: "children",
    label: "label"
  },
  deptTempOptions: [],
  userTableList: [],
  userTotal: 0,
  selectedUserDate: [],
  roleOptions: [],
  roleIds: [],
  deptTreeData: [],
  deptIds: [],
  // 查询参数
  queryParams: {
    deptId: undefined
  },
  showMultiFlog: false,
  isSequential: false,
  multiLoopType: 'Null',
  bpmnElement: undefined,
  selectDeptIds: []
})
const {loading,dataType,selectedUser,userOpen,deptName,deptOptions,deptProps,
  deptTempOptions,userTableList,userTotal,selectedUserDate,roleOptions,roleIds,
  deptTreeData,deptIds,queryParams,showMultiFlog,isSequential,multiLoopType,bpmnElement,selectDeptIds} = toRefs(state)

watch(()=>props.id,() => {
  state.bpmnElement = window.bpmnInstances.bpmnElement;
  proxy.$nextTick(() => resetTaskForm());
},{immediate: true})
watch(()=>state.deptName,(val) => {
  proxy.$refs.tree.filter(val);
})
onUnmounted(() => {
  state.bpmnElement = null;
})
function resetTaskForm() {
  const bpmnElementObj = state.bpmnElement?.businessObject;
  if (!bpmnElementObj) {
    return;
  }
  clearOptionsData()
  state.dataType = bpmnElementObj['dataType'];
  if (state.dataType === 'USERS') {
    let userIdData = bpmnElementObj['candidateUsers'] || bpmnElementObj['assignee'];
    let userText = bpmnElementObj['text'] || [];
    if (userIdData && userIdData.toString().length > 0 && userText && userText.length > 0) {
      state.selectedUser.ids = userIdData?.toString().split(',');
      state.selectedUser.text = userText?.split(',');
    }
    if (state.selectedUser.ids.length > 1) {
      state.showMultiFlog = true;
    }
  } else if (state.dataType === 'ROLES') {
    getRoleOptions();
    let roleIdData = bpmnElementObj['candidateGroups'] || [];
    if (roleIdData && roleIdData.length > 0) {
      state.roleIds = roleIdData.split(',')
    }
    state.showMultiFlog = true;
  } else if (state.dataType === 'DEPTS') {
    getDeptTreeData().then(() => {
      let deptIdData = bpmnElementObj['candidateGroups'] || [];
      if (deptIdData && deptIdData.length > 0) {
        state.deptIds = deptIdData.split(',');
        state.selectDeptIds = deptIdData.split(',');
      }
    });
    state.showMultiFlog = true;
  }
  getElementLoop(bpmnElementObj);
}
/**
 * 清空选项数据
 */
function clearOptionsData() {
  state.selectedUser.ids = [];
  state.selectedUser.text = [];
  state.roleIds = [];
  state.deptIds = [];
}
/**
 * 跟新节点数据
 */
function updateElementTask() {
  const taskAttr = Object.create(null);
  for (let key in userTaskForm) {
      taskAttr[key] = userTaskForm[key];
  }
  window.bpmnInstances.modeling.updateProperties(toRaw(state.bpmnElement), taskAttr);
}
/**
 * 查询部门下拉树结构
 */
function getDeptOptions() {
  return new Promise((resolve, reject) => {
    if (!state.deptOptions || state.deptOptions.length <= 0) {
      deptTreeSelect().then(response => {
        state.deptTempOptions = response.data;
        state.deptOptions = response.data;
        resolve()
      })
    } else {
      reject()
    }
  });
}
const refactorTree = (data) => {
  return data.map(node => {
    let treeData = { id: `DEPT${node.id}`, label: node.label, parentId: node.parentId, weight: node.weight };
    if (node.children && node.children.length > 0) {
      treeData.children = refactorTree(node.children);
    }
    return treeData;
  });
}
/**
 * 查询部门下拉树结构（含部门前缀）
 */
function getDeptTreeData() {

  return new Promise((resolve, reject) => {
    if (!state.deptTreeData || state.deptTreeData.length <= 0) {
      getDeptOptions().then(() => {
        state.deptTreeData = refactorTree(state.deptOptions);
        resolve()
      }).catch(() => {
        reject()
      })
    } else {
      resolve()
    }
  })
}
/**
 * 查询部门下拉树结构
 */
function getRoleOptions() {
  if (!state.roleOptions || state.roleOptions.length <= 0) {
    listRole().then(response => state.roleOptions = response.rows);
  }
}
/** 查询用户列表 */
function getUserList() {
  listUser(proxy.addDateRange(state.queryParams, state.dateRange)).then(response => {
    state.userTableList = response.rows;
    state.userTotal = response.total;
  });
}
// 筛选节点
function filterNode(value, data) {
  if (!value) return true;
  return data.label.indexOf(value) !== -1;
}
// 节点单击事件
function handleNodeClick(data) {
  state.queryParams.deptId = data.id;
  getUserList();
}
// 关闭标签
function handleClose(tag) {
  state.selectedUserDate.splice(state.selectedUserDate.indexOf(tag), 1);
  proxy.$refs.multipleTable.toggleRowSelection(tag);
}
// 多选框选中数据
function handleSelectionChange(selection) {
  state.selectedUserDate = selection;
}
function onSelectUsers() {
  state.selectedUserDate = []
  proxy.$refs.multipleTable?.clearSelection();
  getDeptOptions();
  state.userOpen = true;
}
function handleTaskUserComplete() {
  if (!state.selectedUserDate || state.selectedUserDate.length <= 0) {
    proxy.$modal.msgError('请选择用户');
    return;
  }
  userTaskForm.dataType = 'USERS';
  state.selectedUser.text = state.selectedUserDate.map(k => k.nickName) || [];
  if (state.selectedUserDate.length === 1) {
    let data = state.selectedUserDate[0];
    userTaskForm.assignee = data.userId;
    userTaskForm.text = data.nickName;
    userTaskForm.candidateUsers = null;
    state.showMultiFlog = false;
    state.multiLoopType = 'Null';
    changeMultiLoopType();
  } else {
    userTaskForm.candidateUsers = state.selectedUserDate.map(k => k.userId).join() || null;
    userTaskForm.text = state.selectedUserDate.map(k => k.nickName).join() || null;
    userTaskForm.assignee = null;
    state.showMultiFlog = true;
  }
  updateElementTask()
  state.userOpen = false;
}
function changeSelectRoles(val) {
  let groups = null;
  let text = null;
  if (val && val.length > 0) {
    userTaskForm.dataType = 'ROLES';
    groups = val.join() || null;
    let textArr = state.roleOptions.filter(k => val.indexOf(`ROLE${k.roleId}`) >= 0);
    text = textArr?.map(k => k.roleName).join() || null;
  } else {
    userTaskForm.dataType = null;
    state.multiLoopType = 'Null';
  }
  userTaskForm.candidateGroups = groups;
  userTaskForm.text = text;
  updateElementTask();
  changeMultiLoopType();
}
function checkedDeptChange() {
  let groups = null;
  let text = null;
  let checkedIds = state.selectDeptIds
  state.deptIds = checkedIds;
  if (checkedIds && checkedIds.length > 0) {
    userTaskForm.dataType = 'DEPTS';
    groups = checkedIds.join() || null;
    let textArr = []
    let treeStarkData = JSON.parse(JSON.stringify(state.deptTreeData));
    checkedIds.forEach(id => {
      let stark = []
      stark = stark.concat(treeStarkData);
      while(stark.length) {
        let temp = stark.shift();
        if(temp.children) {
          stark = temp.children.concat(stark);
        }
        if(id === temp.id) {
          textArr.push(temp);
        }
      }
    })
    text = textArr?.map(k => k.label).join() || null;
  } else {
    userTaskForm.dataType = null;
    state.multiLoopType = 'Null';
  }

  userTaskForm.candidateGroups = groups;
  userTaskForm.text = text;
  updateElementTask();
  changeMultiLoopType();
}
function changeDataType(val) {
  if (val === 'ROLES' || val === 'DEPTS' || (val === 'USERS' && state.selectedUser.ids.length > 1)) {
    state.showMultiFlog = true;
  } else {
    state.showMultiFlog = false;
  }
  state.multiLoopType = 'Null';
  changeMultiLoopType();
  // 清空 userTaskForm 所有属性值
  Object.keys(userTaskForm).forEach(key => userTaskForm[key] = null);
  userTaskForm.dataType = val;
  if (val === 'USERS') {
    if (state.selectedUser && state.selectedUser.ids && state.selectedUser.ids.length > 0) {
      if (state.selectedUser.ids.length === 1) {
        userTaskForm.assignee = state.selectedUser.ids[0];
      } else {
        userTaskForm.candidateUsers = state.selectedUser.ids.join()
      }
      userTaskForm.text = state.selectedUser.text?.join() || null
    }
  } else if (val === 'ROLES') {
    getRoleOptions();
    if (state.roleIds && state.roleIds.length > 0) {
      userTaskForm.candidateGroups = state.roleIds.join() || null;
      let textArr = state.roleOptions.filter(k => state.roleIds.indexOf(`ROLE${k.roleId}`) >= 0);
      userTaskForm.text = textArr?.map(k => k.roleName).join() || null;
    }
  } else if (val === 'DEPTS') {
    getDeptTreeData();
    if (state.deptIds && state.deptIds.length > 0) {
      userTaskForm.candidateGroups = state.deptIds.join() || null;
      let textArr = []
      let treeStarkData = JSON.parse(JSON.stringify(state.deptTreeData));
      state.deptIds.forEach(id => {
        let stark = []
        stark = stark.concat(treeStarkData);
        while(stark.length) {
          let temp = stark.shift();
          if(temp.children) {
            stark = temp.children.concat(stark);
          }
          if(id === temp.id) {
            textArr.push(temp);
          }
        }
      })
      userTaskForm.text = textArr?.map(k => k.label).join() || null;
    }
  } else if (val === 'INITIATOR') {
    userTaskForm.assignee = "${initiator}";
    userTaskForm.text = "流程发起人";
  }
  updateElementTask();
}
function getElementLoop(businessObject) {
  if (!businessObject.loopCharacteristics) {
    state.multiLoopType = "Null";
    return;
  }
  state.isSequential = businessObject.loopCharacteristics.isSequential;
  if (businessObject.loopCharacteristics.completionCondition) {
    if (businessObject.loopCharacteristics.completionCondition.body === "${nrOfCompletedInstances >= nrOfInstances}") {
      state.multiLoopType = "SequentialMultiInstance";
    } else {
      state.multiLoopType = "ParallelMultiInstance";

    }
  }
}
function changeMultiLoopType() {
  // 取消多实例配置
  if (state.multiLoopType === "Null") {
    window.bpmnInstances.modeling.updateProperties(toRaw(state.bpmnElement), { loopCharacteristics: null, assignee: null });
    return;
  }
  let multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", { isSequential: state.isSequential });
  // 更新多实例配置
  window.bpmnInstances.modeling.updateProperties(toRaw(state.bpmnElement), {
    loopCharacteristics: multiLoopInstance,
    assignee: '${assignee}'
  });
  // 完成条件
  let completionCondition = null;
  // 会签
  if (state.multiLoopType === "SequentialMultiInstance") {
    completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: "${nrOfCompletedInstances >= nrOfInstances}" });
  }
  // 或签
  if (state.multiLoopType === "ParallelMultiInstance") {
    completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: "${nrOfCompletedInstances > 0}" });
  }
  // 更新模块属性信息
  window.bpmnInstances.modeling.updateModdleProperties(toRaw(state.bpmnElement), multiLoopInstance, {
    collection: '${multiInstanceHandler.getUserIds(execution)}',
    elementVariable: 'assignee',
    completionCondition
  });
}


</script>

<style scoped lang="scss">
.el-row .el-radio-group {
  margin-bottom: 15px;
  .el-radio {
    line-height: 28px;
  }
}
.el-tag {
  margin-bottom: 10px;
  + .el-tag {
    margin-left: 10px;
  }
}

.custom-label {
  padding-left: 5px;
  font-weight: 500;
  font-size: 14px;
  color: #606266;
}

</style>
